%{
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "xcompiler.h"
extern int yylex();
%}

%union{
  struct ast *a;
}

%token <a> INTEGER
%token <a> TYPE ID SEMI ASSIGN PLUS MINUS LP RP
%type <a> Program StmtList Stmt Exp

%right ASSIGN
%left PLUS MINUS
%left LP RP

%%

Program:StmtList {$$=newast("Program",1,$1);eval($$,0);}
       ;

StmtList: /*Nothing*/ {$$=newast("StmtList",0,-1);}
        |Stmt StmtList {$$=newast("StmtList",2,$1,$2);}
        ;

Stmt:Exp SEMI {$$=newast("Stmt",2,$1,$2);}
    ;

Exp:Exp ASSIGN Exp {$$=newast("Exp",3,$1,$2,$3);}
   | Exp PLUS Exp { $$ = newast("Exp", 3, $1, $2, $3); }
   | Exp MINUS Exp { $$ = newast("Exp", 3, $1, $2, $3); }
   | LP Exp RP { $$ = newast("Exp", 3, $1, $2, $3); }
   | INTEGER { $$ = newast("Exp", 1, $1); }
   | ID {$$ = newast("Exp",1,$1);}
   ;

%%

void yyerror(char *s, ...){
  fprintf(stderr, "%d: error: ", yylineno);
  fprintf(stderr, "\n");
}
